package demo.controller;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.http.client.ClientProtocolException;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.jweb.core.bean.MultipartNameValuePair;
import org.jweb.core.bean.PageMode;
import org.jweb.core.bean.ReplyDataMode;
import org.jweb.core.bean.UploadFileMode;
import org.jweb.core.query.hibernate.qbc.CriteriaQuery;
import org.jweb.core.util.DateUtil;
import org.jweb.core.util.FileUtil;
import org.jweb.core.util.HttpClientUtil;
import org.jweb.core.util.ResourceUtil;
import org.jweb.core.util.StringUtil;
import org.jweb.core.web.controller.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import cn.keepme.ep.auth.transfer.vo.authen.AuthUserVO;
import cn.keepme.ep.common.event.Sender;
import cn.keepme.ep.common.event.SysEvent;
import cn.keepme.ep.common.service.SMSServiceI;
import cn.keepme.ep.common.service.SysServiceI;

import com.alibaba.fastjson.JSONObject;

import demo.entity.AnalyzeCategoryEntity;
import demo.entity.AnalyzeMsgEntity;
import demo.entity.AnalyzeRoomEntity;
import demo.entity.RoomVoteEntity;
import demo.service.VoteServiceI;
import demo.trans.form.RoomMsgSearchForm;
import demo.trans.form.RoomSearchForm;
import demo.trans.form.RoomVoteSearchForm;
import demo.trans.vo.RoomCategoryVO;
import demo.trans.vo.RoomMsgVO;
import demo.trans.vo.RoomVO;

@Controller
@RequestMapping("/room")
public class RoomController  extends BaseController{
	private static final Logger logger = Logger.getLogger(RoomController.class);
	@Autowired
	private SysServiceI sysService;
	@Autowired
	private SMSServiceI smsService;
	
	@Autowired
	private VoteServiceI voteService;
	@Autowired
	private Sender sender;
	
	
	/**
	 * 根据查询条件查询接盘房间列表,无分页
	 * @param searchForm
	 * @param req
	 * @return
	 */
	@RequestMapping(value = "/roomList")
	@ResponseBody
	public ReplyDataMode roomList(RoomSearchForm searchForm,HttpServletRequest req){
		ReplyDataMode j = new ReplyDataMode();
		CriteriaQuery cq = searchForm.getCriteriaQuery();
		List<AnalyzeRoomEntity> entityList = this.sysService.list(cq);
		List<RoomVO> voList = new ArrayList<RoomVO>();
		for(AnalyzeRoomEntity e : entityList){
			RoomVO vo = new RoomVO();
			vo.copyEntity(e);
			
//			List<RoomVoteEntity> voteEntitys = e.getVotes();
//			for(RoomVoteEntity v : voteEntitys){
//				RoomVoteVO voteVO = new RoomVoteVO();
//				voteVO.copyEntity(v);
//				vo.getVotes().add(voteVO);
//			}
			voList.add(vo);
		}
		
		j.setData(voList);
		j.setSuccess(true);
		return j;
	}
	
	/**
	 * 查询全部分类列表
	 * @param req
	 * @return
	 */
	@RequestMapping(value = "/categoryList")
	@ResponseBody
	public ReplyDataMode categoryList(HttpServletRequest req){
		ReplyDataMode j = new ReplyDataMode();
		List<AnalyzeCategoryEntity> entityList = this.sysService.getList(AnalyzeCategoryEntity.class);
		List<RoomCategoryVO> voList = new ArrayList<RoomCategoryVO>();
		for(AnalyzeCategoryEntity e : entityList){
			RoomCategoryVO vo = new RoomCategoryVO();
			vo.copyEntity(e);
			voList.add(vo);
		}
		
		j.setData(voList);
		j.setSuccess(true);
		return j;
	}
	
	/**
	 * 判断是否可以在房间发言
	 * @param mphone
	 * @param req
	 * @return
	 */
	@RequestMapping(value = "/speekable")
	@ResponseBody
	@RequiresAuthentication
	@RequiresRoles(value="jpls")
	public ReplyDataMode speekable(HttpServletRequest req){
		ReplyDataMode j = new ReplyDataMode();
		Subject currentUser = SecurityUtils.getSubject();
		if(currentUser.hasRole("jpls")){
			j.setSuccess(true);
		}
		j.setSuccess(false);
		return j;
	}
	
	@RequestMapping(value = "/speek")
	@ResponseBody
	@RequiresAuthentication
	@RequiresRoles(value="jpls")
	public ReplyDataMode speek(String content,String roomId,HttpServletRequest req){
		ReplyDataMode j = new ReplyDataMode();
		Subject currentUser = SecurityUtils.getSubject();
		AuthUserVO userEntity = (AuthUserVO)currentUser.getSession().getAttribute("userInfo");
		logger.info("current user :"+userEntity.getMphone()+", speeking :" +content);
		
		AnalyzeMsgEntity msgEntity = new AnalyzeMsgEntity();
		msgEntity.setContent(content);
		msgEntity.setAuthor(userEntity.getNick());
		AnalyzeRoomEntity roomEntity = sysService.get(AnalyzeRoomEntity.class, roomId);
		msgEntity.setAnalyzeRoom(roomEntity);
		Date publishTime = new Date();
		msgEntity.setPublishTime(publishTime);
		this.sysService.saveOrUpdate(msgEntity);
		
		//产生事件，用于通过websocket告知前端页面刷新
		RoomMsgVO msgVO = new RoomMsgVO();
		msgVO.copyEntity(msgEntity);
		String msgVOJson = JSONObject.toJSONString(msgVO);
//		Map<String,Object> msgObj = new HashMap<String,Object>();
//		msgObj.put("content", content);
//		msgObj.put("author", userEntity.getNick());
//		msgObj.put("roomId", roomId);
//		SimpleDateFormat format = new SimpleDateFormat("HH:mm");
//		msgObj.put("publishTime", format.format(publishTime));
		
		final HashMap<String,Object> attr = new HashMap<String,Object>();
		attr.put("data", msgVOJson);
		
		sender.send(new SysEvent("roomSpeeked",attr));
		
		j.setSuccess(true);
		return j;
	}
	
	@RequestMapping(value = "/get")
	@ResponseBody
	public ReplyDataMode get(String roomId){
		ReplyDataMode j = new ReplyDataMode();
		AnalyzeRoomEntity roomEntity = this.sysService.get(AnalyzeRoomEntity.class, roomId);
		RoomVO roomVO = new RoomVO();
		try{
			roomVO.copyEntity(roomEntity);
		} catch(Exception e){
			e.printStackTrace();
		}
		
		
		j.setData(roomVO);
		j.setSuccess(true);
		return j;
	}
	
	/**
	 * 投票
	 * @param searchForm
	 * @return
	 */
	@RequestMapping(value = "/voting")
	@ResponseBody
	public ReplyDataMode voting(RoomVoteSearchForm searchForm){
		ReplyDataMode j = new ReplyDataMode();
		voteService.voting(searchForm.getId());
		RoomVoteEntity voteEntity = this.sysService.get(RoomVoteEntity.class, searchForm.getId());
		AnalyzeRoomEntity roomEntity = voteEntity.getRoom();
		RoomVO roomVO = new RoomVO();
		roomVO.copyEntity(roomEntity);
		
		String roomVOJson = JSONObject.toJSONString(roomVO);
		//产生事件，用于通过websocket告知前端页面刷新
		final HashMap<String,Object> attr = new HashMap<String,Object>();
		attr.put("data", roomVOJson);
		
		sender.send(new SysEvent("roomVoted",attr));
		
		j.setSuccess(true);
		return j;
	}
	
	/**
	 * 删除某条信息
	 * @param msgId
	 * @return
	 */
	@RequestMapping(value = "/delMsg")
	@ResponseBody
	public ReplyDataMode delMsg(String msgId){
		ReplyDataMode j = new ReplyDataMode();
		String roomId = "";
		if(StringUtil.isNotEmpty(msgId)){
//			this.sysService.deleteEntityById(AnalyzeMsgEntity.class, msgId);
			AnalyzeMsgEntity msgEntity = this.sysService.get(AnalyzeMsgEntity.class, msgId);
			if(msgEntity != null){
				roomId = msgEntity.getAnalyzeRoom().getId();
			}
			//没有搞懂为啥hibernate就不执行删除语句了
			String delSql = "delete from tp_analyze_msg where id = ?";
			this.voteService.executeSql(delSql, new Object[]{msgId});
//			this.voteService.delete(msgEntity);
		}
		//产生事件，用于通过websocket告知前端页面刷新
		RoomMsgVO msgVO = new RoomMsgVO();
		msgVO.setId(msgId);
		msgVO.setRoomId(roomId);
		String msgVOJson = JSONObject.toJSONString(msgVO);
		final HashMap<String,Object> attr = new HashMap<String,Object>();
		attr.put("data", msgVOJson);
		
		sender.send(new SysEvent("roomSpeekMsgDeleted",attr));
		
		j.setSuccess(true);
		return j;
	}
	
	/**
	 * 迈普官方投票
	 * @param searchForm
	 * @return
	 */
	@RequestMapping(value = "/mpeVoting")
	@ResponseBody
	@RequiresAuthentication
	@RequiresRoles(value="jpls")
	public ReplyDataMode mpeVoting(String mpePoint,String roomId){
		ReplyDataMode j = new ReplyDataMode();
		AnalyzeRoomEntity roomEntity = this.sysService.get(AnalyzeRoomEntity.class, roomId);
		roomEntity.setMpe(mpePoint);
		this.sysService.saveOrUpdate(roomEntity);
		
		RoomVO roomVO = new RoomVO();
		roomVO.copyEntity(roomEntity);
		String roomVOJson = JSONObject.toJSONString(roomVO);
		//产生事件，用于通过websocket告知前端页面刷新
		final HashMap<String,Object> attr = new HashMap<String,Object>();
		attr.put("data", roomVOJson);
		
		sender.send(new SysEvent("roomVoted",attr));
		
		j.setSuccess(true);
		return j;
	}
	
	/**
	 * 查询解盘大厅消息
	 * @param searchForm
	 * @param pageNo
	 * @param pageSize
	 * @return
	 */
	@RequestMapping(value = "/msgList")
	@ResponseBody
	public ReplyDataMode msgList(RoomMsgSearchForm searchForm,int pageNo,int pageSize){
		ReplyDataMode j = new ReplyDataMode();
		
		String publishTime = searchForm.getPublishTimeBegin();
		if(StringUtil.isEmpty(publishTime)){
			/**时间范围计算开始*/
			//获取发布时间范围，单位天，查询从当前时间推后该时间起到现在时间范围内的消息数据，防止全库查询，导致数据过多
			String publicTimeRang = ResourceUtil.getConfigByName("hall_msg_public_time_rang");
			long timeRang = Long.parseLong(publicTimeRang);
			timeRang = timeRang*24*60*60*1000;
			long curTime = System.currentTimeMillis();
			long startTime = curTime - timeRang;
			Date startPublishTime = new Date(startTime);
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String startPublishTimeStr = format.format(startPublishTime);
			searchForm.setPublishTimeBegin(startPublishTimeStr);
			searchForm.emptyValue2NullValue();
			/**时间范围计算结束*/
		} 
		
		
		CriteriaQuery cq = searchForm.getCriteriaQuery();
		Map<String,Object> orderMap = new HashMap<String,Object>();
		orderMap.put("publishTime", "asc");
		cq.setOrder(orderMap);
		List msgEntityList = this.sysService.list(cq);
		List<RoomMsgVO> msgVOList = new ArrayList<RoomMsgVO>();
		RoomMsgVO vo = null;
		SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd");
		for(Object o : msgEntityList){
			AnalyzeMsgEntity e = (AnalyzeMsgEntity)o;
			 vo = new RoomMsgVO();
			vo.copyEntity(e);
			vo.setPublishDate(format2.format(e.getPublishTime()));
			msgVOList.add(vo);
		}
		
		j.setData(msgVOList);
		
		j.setSuccess(true);
		return j;
	}
	
	@RequestMapping(value = "/msgPage")
	@ResponseBody
	public ReplyDataMode msgPage(RoomMsgSearchForm searchForm,int pageNo,int pageSize){
		ReplyDataMode j = new ReplyDataMode();
		
		// 参数问题，以后删
//		pageNo=2;  
		
		/**时间范围计算开始*/
		//获取发布时间范围，单位天，查询从当前时间推后该时间起到现在时间范围内的消息数据，防止全库查询，导致数据过多
		String publicTimeRang = ResourceUtil.getConfigByName("hall_msg_public_time_rang");
		long timeRang = Long.parseLong(publicTimeRang);
		timeRang = timeRang*24*60*60*1000;
		long curTime = System.currentTimeMillis();
		long startTime = curTime - timeRang;
		Date startPublishTime = new Date(startTime);
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String startPublishTimeStr = format.format(startPublishTime);
		searchForm.setPublishTimeBegin(startPublishTimeStr);
		searchForm.emptyValue2NullValue();
		/**时间范围计算结束*/
		
		CriteriaQuery cq = searchForm.getCriteriaQuery();
		Map<String,Object> orderMap = new HashMap<String,Object>();
		orderMap.put("publishTime", "asc");
		cq.setOrder(orderMap);
		
		// 分页问题，已修改，by wupan
//		PageMode msgEntityPage = this.sysService.list4page(cq, pageSize, pageNo);
		PageMode msgEntityPage = this.sysService.list4page(cq, pageNo, pageSize);
		
		List<AnalyzeMsgEntity> msgEntityList = msgEntityPage.getResult();
		List<RoomMsgVO> msgVOList = new ArrayList<RoomMsgVO>();
		SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd");
		for(AnalyzeMsgEntity e : msgEntityList){
			RoomMsgVO vo = new RoomMsgVO();
			vo.copyEntity(e);
			vo.setPublishDate(format2.format(e.getPublishTime()));
			msgVOList.add(vo);
		}
		msgEntityPage.setResult(msgVOList);
		j.setData(msgEntityPage);
		
		j.setSuccess(true);
		return j;
	}
	
	
	
	@RequestMapping(value = "/upload")
	@ResponseBody
	public ReplyDataMode upload(String roomId, HttpServletRequest request) {
		ReplyDataMode j = new ReplyDataMode();
		
		//保存附近图片信息
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
		Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
		
		
		UploadFileMode uploadFileMode = null;
		
		for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
			MultipartFile mf = entity.getValue();// 获取上传文件对象
			try {
				uploadFileMode = this.saveTempImg(request, mf);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			// 零时图片存放目录下的图片将会定期删除
//			request.getSession().setAttribute("lastPhotoSaveResultMap",
//					saveResultMap);
			break;// 这里业务上是单传头像，故只循环一次

		}
		
		
		if(uploadFileMode != null){
			
			//将图片转移到远程文件系统
			try {
				uploadFileMode = this.save2RemoteTempDir(uploadFileMode);
				AnalyzeMsgEntity msgEntity = new AnalyzeMsgEntity();
				msgEntity.setContent("<img src='"+uploadFileMode.getTempUrl()+"' />");
				AnalyzeRoomEntity roomEntity = sysService.get(AnalyzeRoomEntity.class, roomId);
				msgEntity.setAnalyzeRoom(roomEntity);
				this.sysService.saveOrUpdate(msgEntity);
				
				//产生事件，用于通过websocket告知前端页面刷新
				RoomMsgVO msgVO = new RoomMsgVO();
				msgVO.copyEntity(msgEntity);
				String msgVOJson = JSONObject.toJSONString(msgVO);
				
				final HashMap<String,Object> attr = new HashMap<String,Object>();
				attr.put("data", msgVOJson);
				
				sender.send(new SysEvent("roomSpeeked",attr));
				
				j.setSuccess(true);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				j.setSuccess(false);
			}
			
		}

		return j;
	}
	
	
	/**
	 * 上传文件保存到临时目录
	 * 返回的map对象，主要包含这几个键：
	 * tempDirPath:文件存放的临时目录路径"webpage/tisdweb/upload/temp/20140327/",相对路径
	 * tempDirRealPath：c:/workspace/tisd_web/webpage/tisdweb/upload/temp/20140327/,绝对路径
	 * fileExtend:文件扩展名，如jpg,png
	 * fileName:文件在临时目录中存放时的名称，如dog.jpg
	 * fileFullName:文件全路径名，如c:/workspace/tisd_web/webpage/tisdweb/upload/temp/20140327/dog.jpg
	 * @param request
	 * @param mf
	 * @return
	 * @throws IOException
	 */
	protected UploadFileMode saveTempImg(HttpServletRequest request,
			MultipartFile mf) throws IOException {

//		Map<String, String> paramMap = new HashMap<String, String>();
		UploadFileMode uploadFileMode = new UploadFileMode();

		String tempDirPath = "webpage/upload/temp/";
		

		// 文件数据库保存路径
		String realPath = request.getSession().getServletContext()
				.getRealPath("/")
				+ tempDirPath;

		File file = new File(realPath);
		if (!file.exists()) {
			file.mkdirs();// 创建根目录
		}
		
		//用日期分别存放临时文件，以便后期采用定时任务清理临时文件限定清理范围
		String dateDirName = DateUtil.getDataString(DateUtil.yyyyMMdd);
		tempDirPath = tempDirPath + dateDirName + "/";
		realPath += dateDirName + "/";
		file = new File(realPath);
		if (!file.exists()) {
			file.mkdir();// 创建文件时间子目录
		}
		
		uploadFileMode.setTempDirPath(tempDirPath);// 将存放临时文件的目录放入返回mode中
		uploadFileMode.setTempDirRealPath(realPath);
		
		
		// 设置文件上传路径
		String noextfilename = "";// 不带扩展名

		String fileName = mf.getOriginalFilename();// 获取文件名
		String extend = FileUtil.getExtend(fileName);// 获取文件扩展名
		uploadFileMode.setFileExtend(extend);
		
		// 重命名
		noextfilename = DateUtil.getDataString(DateUtil.yyyymmddhhmmss)
				+ StringUtil.random(8);// 自定义文件名称
		String myfilename = noextfilename + "." + extend;// 自定义文件名称

		String savePath = realPath + myfilename;// 文件保存全路径

		uploadFileMode.setFileName(myfilename);
		uploadFileMode.setFileFullName(savePath);

		File savefile = new File(savePath);

		// 文件拷贝到指定硬盘目录
		FileCopyUtils.copy(mf.getBytes(), savefile);

		return uploadFileMode;
	}
	
	/**
	 * 将saveResultMap
	 * @param saveResultMap
	 * @param request
	 * @return
	 * @throws IOException 
	 * @throws ClientProtocolException 
	 */
	protected UploadFileMode save2RemoteTempDir(UploadFileMode uploadFileMode) throws ClientProtocolException, IOException{
		String domain = ResourceUtil.getConfigByName("file_server_domain");
		String uploadImgUri = ResourceUtil.getConfigByName("file_server_upload_img_uri");
		String uploadImgUrl = domain+uploadImgUri;
		
		
		// 做文件上传处理
		List<MultipartNameValuePair> mnvps = new ArrayList<MultipartNameValuePair>();
		String fileFullName = uploadFileMode.getFileFullName();
		if(!StringUtil.isEmpty(fileFullName)){
			File file = new File(fileFullName);
			mnvps.add(new MultipartNameValuePair("upfile", file));
		
		}
		
		String result =  HttpClientUtil.sendPost2(uploadImgUrl, mnvps);
		if(!StringUtil.isEmpty(result)){
			JSONObject jsonObj = JSONObject.parseObject(result);
			if("SUCCESS".equals(jsonObj.getString("state"))){
				String tempUrl = jsonObj.getString("url");
				uploadFileMode.setTempUrl(domain + "/" + tempUrl);
			}
		}
		return uploadFileMode;
	}
}
